//
//  HandeAR.m
//  HandeAR
//
//  Created by HandeIdealVision on 2017/10/30.
//  Copyright © 2017年 HandeIdealVison. All rights reserved.
//

#import "HandeAR.h"
#import "UnityAppController.h"
#include "RegisterMonoModules.h"
#include "RegisterFeatures.h"
#include <csignal>
#import "HandeAR+Private.h"
#include <mach/mach_time.h>
#import <AVFoundation/AVFoundation.h>


void UnityInitTrampoline();
void s_Il2CppCodegenRegistration();

@interface HandeAR()
@property (nonatomic, strong) UnityAppController *unityController;


@property(nonatomic) BOOL loginStatus;
@property(nonatomic, strong) NSString *publishTime;
@property(nonatomic, strong) NSString *arResourceURL;
@property(nonatomic, strong) NSString *annualReport;
@property(nonatomic, strong) NSString *layoutParam;

@property(nonatomic) BOOL needSaved;
@property(nonatomic) BOOL alreadyInitSDK;
@end

@implementation HandeAR

+ (void)load {
//    [HandeAR sharedInstance];
}

- (void)registerNotification {
    NSNotificationCenter *center = [NSNotificationCenter defaultCenter];
    [center addObserver:self selector:@selector(applicationWillResignActive:) name:UIApplicationWillResignActiveNotification object:nil];
    [center addObserver:self selector:@selector(applicationDidEnterBackground:) name:UIApplicationDidEnterBackgroundNotification object:nil];
    [center addObserver:self selector:@selector(applicationWillEnterForeground:) name:UIApplicationWillEnterForegroundNotification object:nil];
    [center addObserver:self selector:@selector(applicationDidBecomeActive:) name:UIApplicationDidBecomeActiveNotification object:nil];
    [center addObserver:self selector:@selector(applicationWillTerminate:) name:UIApplicationWillTerminateNotification object:nil];
    [center addObserver:self selector:@selector(didFinishLaunchingWithOptions:) name:UIApplicationDidFinishLaunchingNotification object:nil];
}

- (void)unRegisterNotification {
    NSNotificationCenter *center = [NSNotificationCenter defaultCenter];
    [center removeObserver:self];
}


- (instancetype)init {
    self = [super init];
    if (self) {
        [self registerNotification];
        self.needSaved = YES;    //default is need to saved image when snap shot
    }
    
    return self;
}

+ (void)setLoginStatus:(BOOL)isLogined {
    [self registerSDK];
    [HandeAR sharedInstance].loginStatus = isLogined;
}

+ (void)setAnnualReport:(NSString *)jsonString {
    [self registerSDK];
    [HandeAR sharedInstance].annualReport = jsonString;
}

//设置发布数据
+ (void)setPublishTime:(NSString *)time {
    [self registerSDK];
    [HandeAR sharedInstance].publishTime = time;
}

//设置AR资源下载目录，程序拼接
+ (void)setARResourceURL:(NSString *)url {
    [self registerSDK];
    [HandeAR sharedInstance].arResourceURL = url;
}

//5. 设置页面布局，上面高度，下面高度
+ (void)setLayoutTopHeight:(CGFloat)tHeight bottomHeight:(CGFloat)bHeight {
    CGFloat scale = [UIScreen mainScreen].scale;
    [HandeAR sharedInstance].layoutParam = [NSString stringWithFormat:@"%.2f:%.2f", bHeight * scale, tHeight * scale];
}

+ (void)setDelegate:(id<HandeARDelegate>)delegate {
    [self registerSDK];
    [HandeAR sharedInstance].delegate = delegate;
}

+ (void)pauseAudio {
    [[HandeAR sharedInstance] pauseAudio];
}

+ (void)resumeAudio {
    [[HandeAR sharedInstance] unPauseAudio];
}

+ (void)saveImageWhenSnapshot:(BOOL)needSaved {
    [HandeAR sharedInstance].needSaved = needSaved;
}

- (void)dealloc {
    [self unRegisterNotification];
}

#pragma mark - NotificationHander
- (void)applicationWillResignActive:(NSNotification *)notice {
    [self.unityController applicationWillResignActive:[UIApplication sharedApplication]];
}

- (void)applicationDidEnterBackground:(NSNotification *)notice {
//    [self.unityController applicationDidEnterBackground:[UIApplication sharedApplication]];
}

- (void)applicationWillEnterForeground:(NSNotification *)notice {
    [[AVAudioSession sharedInstance] setActive:YES error:nil];
    [self.unityController applicationWillEnterForeground:[UIApplication sharedApplication]];
}

- (void)applicationDidBecomeActive:(NSNotification *)notice {
//    [self.unityController applicationDidBecomeActive:[UIApplication sharedApplication]];
}

- (void)applicationWillTerminate:(NSNotification *)notice {
    [self.unityController applicationWillTerminate:[UIApplication sharedApplication]];
}

- (void)didFinishLaunchingWithOptions:(NSNotification *)notice {
    NSDictionary* launchOptions = [notice userInfo];
    UIApplication *application = [notice object];
    [self application:application didFinishLaunchingWithOptions:launchOptions];
}

+ (UIView *)raView {
    return UnityGetGLView();
}

char ** cArrayFromNSArray ( NSArray* array ){
    int i, count = array.count;
    char **cargs = (char**) malloc(sizeof(char*) * (count + 1));
    for(i = 0; i < count; i++) {        //cargs is a pointer to 4 pointers to char
        NSString *s      = array[i];     //get a NSString
        const char *cstr = s.UTF8String; //get cstring
        int          len = strlen(cstr); //get its length
        char  *cstr_copy = (char*) malloc(sizeof(char) * (len + 1));//allocate memory, + 1 for ending '\0'
        strcpy(cstr_copy, cstr);         //make a copy
        cargs[i] = cstr_copy;            //put the point in cargs
    }
    cargs[i] = NULL;
    return cargs;
}

- (BOOL)application:(UIApplication*)application didFinishLaunchingWithOptions:(NSDictionary*)launchOptions {
    unsigned long long startTime = mach_absolute_time();
    UnitySetStartupTime(startTime);
    UnityInitTrampoline();
    NSArray *array = [[NSProcessInfo processInfo] arguments];
    int count = [array count];
    s_Il2CppCodegenRegistration();
    UnityInitRuntime(count, cArrayFromNSArray(array));
//    s_Il2CppCodegenRegistration();
//    NSString *path = [[NSBundle mainBundle] executablePath];
//    char *argc[] = {(char *)[path UTF8String]};
//    UnityInitRuntime(1, argc);
    
    RegisterMonoModules();
    RegisterFeatures();
    
    // iOS terminates open sockets when an application enters background mode.
    // The next write to any of such socket causes SIGPIPE signal being raised,
    // even if the request has been done from scripting side. This disables the
    // signal and allows Mono to throw a proper C# exception.
    std::signal(SIGPIPE, SIG_IGN);
    
    
    UnityAppController *unityController = [[UnityAppController alloc] init];
    [[HandeAR sharedInstance] setValue:unityController forKey:@"unityController"];
    [unityController application:[UIApplication sharedApplication] didFinishLaunchingWithOptions:nil];
//    [unityController applicationWillResignActive:[UIApplication sharedApplication]];

    return YES;
}

+ (void)preSetup {
    UnityAppController *unityController = [[HandeAR sharedInstance] valueForKey:@"unityController"];
    [unityController applicationDidBecomeActive:[UIApplication sharedApplication]];
}

+ (void)registerSDK {
    if (![HandeAR sharedInstance].alreadyInitSDK) {
        [HandeAR sharedInstance].alreadyInitSDK = YES;
        [[HandeAR sharedInstance] didFinishLaunchingWithOptions:nil];
    }
}

@end

#if TARGET_IPHONE_SIMULATOR && TARGET_TVOS_SIMULATOR

#include <pthread.h>

extern "C" int pthread_cond_init$UNIX2003(pthread_cond_t *cond, const pthread_condattr_t *attr)
{ return pthread_cond_init(cond, attr); }
extern "C" int pthread_cond_destroy$UNIX2003(pthread_cond_t *cond)
{ return pthread_cond_destroy(cond); }
extern "C" int pthread_cond_wait$UNIX2003(pthread_cond_t *cond, pthread_mutex_t *mutex)
{ return pthread_cond_wait(cond, mutex); }
extern "C" int pthread_cond_timedwait$UNIX2003(pthread_cond_t *cond, pthread_mutex_t *mutex,
                                               const struct timespec *abstime)
{ return pthread_cond_timedwait(cond, mutex, abstime); }

#endif // TARGET_IPHONE_SIMULATOR && TARGET_TVOS_SIMULATOR
